<script setup lang="ts">
import type { FolderProps } from '@/types';

import {
  type ComponentInternalInstance,
  defineAsyncComponent,
  getCurrentInstance,
  hydrateOnVisible,
  nextTick,
  onMounted,
  onUnmounted,
  ref,
  useTemplateRef,
} from 'vue';

import { Icon } from '@/components/core/icon';

import {
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElMessageBox,
} from 'element-plus';
import videoJs from 'video.js';
import video_zhCN from 'video.js/dist/lang/zh-CN.json';

import 'video.js/dist/video-js.css';

defineOptions({
  name: 'VideoPlayer',
});
const { app } = defineProps({
  app: {
    default: () => ({}),
    type: Object,
  },
});
// demo url: https://media.w3.org/2010/05/sintel/trailer.mp4

const SelectByFileType = defineAsyncComponent({
  hydrate: hydrateOnVisible(),
  loader: () => import('../_core/common/SelectByFileType.vue'),
});
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const baseUrl = proxy?.$config.baseUrl;
const selectByFileTypeRef = useTemplateRef('selectByFileTypeRef');
const videoPlayer = useTemplateRef('videoPlayer');
const videoPath = app?.data?.fullPath || '';
const videoSrc = ref(`${baseUrl}/video?path=${videoPath}`);
const showPlayer = ref(false);
const filters = proxy?.$config.filter?.video || [];
// 视频播放器配置
const options = ref({
  aspectRatio: '16:9', // 将播放器置于流畅模式，并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字（例如"16:9"或"4:3"）
  autoplay: 'any', // 如果true,浏览器准备好时开始回放。
  controlBar: {
    durationDisplay: true,
    fullscreenToggle: true, // 全屏按钮
    remainingTimeDisplay: false,
    timeDivider: true,
  },
  controls: true,
  fluid: true, // 当true时，Video.js player将拥有流体大小。换句话说，它将按比例缩放以适应其容器。
  language: 'zh-CN',
  loop: true, // 导致视频一结束就重新开始。
  muted: true, // 默认情况下将会消除任何音频。
  notSupportedMessage: '此视频暂无法播放，请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
  playbackRates: [0.7, 1, 1.5, 2], // 播放速度
  preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频（如果浏览器支持）
});

const onOpen = () => {
  selectByFileTypeRef.value?.open({ exts: filters, title: '选择视频文件' });
};
// 打开地址
const onOpenHttp = () => {
  ElMessageBox.prompt('请输入播放文件地址', '打开视频URL', {
    buttonSize: 'small',
    cancelButtonText: '取消',
    closeOnClickModal: false,
    confirmButtonText: '确定',
    customClass: 'wos-common-confirm',
    draggable: true,
    inputPlaceholder: '输入文件、流的URL',
  })
    .then(({ value }) => {
      videoSrc.value = value;
      showPlayer.value = true;
    })
    .catch(() => {
      console.log('取消');
    });
};
const handleCommand = (command: number | object | string) => {
  switch (command) {
    case 'file': {
      onOpen();
      break;
    }
    case 'url': {
      onOpenHttp();
      break;
    }
  }
};
const onDispose = () => {
  showPlayer.value = false;
  videoSrc.value = '';
};
const onConfirm = (item: FolderProps) => {
  videoSrc.value = `${baseUrl}/video?path=${item.fullPath}`;
  showPlayer.value = true;
};
onMounted(() => {
  videoJs.addLanguage('zh-CN', video_zhCN);
  nextTick(() => {
    if (videoPlayer.value) {
      videoJs(videoPlayer.value, options.value, function onPlayerReady() {
        // In this context, `this` is the player that was created by Video.js.
        this.play();
      });
    }
  });
});
onUnmounted(() => {
  onDispose();
});
</script>
<template>
  <div class="wos-video-player">
    <div v-if="!videoPath && !showPlayer" class="video-player-placeholder">
      <ElDropdown
        size="small"
        split-button
        type="primary"
        @click="onOpen"
        @command="handleCommand"
      >
        打开文件

        <template #dropdown>
          <ElDropdownMenu>
            <ElDropdownItem command="url">打开地址</ElDropdownItem>
            <ElDropdownItem command="file">打开文件</ElDropdownItem>
          </ElDropdownMenu>
        </template>
      </ElDropdown>
    </div>
    <div v-else class="video-player-box">
      <div class="close" @click="onDispose">
        <Icon icon="ant-design:close-outlined" size="24" />
      </div>
      <video ref="videoPlayer" class="video-js" controls webkit-playsinline>
        <source :src="videoSrc" />
      </video>
    </div>
    <SelectByFileType ref="selectByFileTypeRef" @confirm="onConfirm" />
  </div>
</template>
<style lang="scss">
.wos-video-player {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: rgb(14 14 14);

  video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  .video-js,
  .v-video-player {
    height: 100% !important;
  }

  .video-player-placeholder {
    position: relative;
    display: flex;
    place-content: center center;
    align-items: center;
    width: 100%;
    height: 100%;

    &::before {
      position: absolute;
      top: 50%;
      left: 50%;
      font-size: 36px;
      content: 'tOS Video Player';
      transform: translate(-50%, calc(-50% - 64px));
    }
  }

  .video-player-box {
    position: relative;
    width: 100%;
    height: 100%;

    .close {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 9999;
      padding: 6px;
      cursor: pointer;
      background-color: #393939;
      border-radius: 3px;
      opacity: 0;
    }

    &:hover {
      .close {
        opacity: 1;

        &:hover {
          background-color: #595959;
        }
      }
    }
  }
}
</style>
